﻿/*
 * Created by SharpDevelop.
 * User: Edward Wilde (http://blogs.charteris.com/edwardw)
 * Date: 05/07/2007
 * Time: 17:14
 */

using Wax;
using System;
using NUnit.Framework;

namespace WaxLibTest
{
	/// <summary>
	/// Tests the behaviour of the <see cref="CommandFactory". />
	/// </summary>
	[TestFixture]
	public class CommandFactoryTest
	{
		
		/// <summary>
		/// Tests that property types can be correctly parsed
		/// </summary>
		[Test]
		public void ParsePropertyType()
		{
			Assert.AreEqual(PropertyType.Text, CommandFactory.ParsePropertyType("Text"));
		}
		
		/// <summary>
		/// Tests that parsing a property thows an exception when trying to parse an unknown value.
		/// </summary>
		[Test, ExpectedExceptionAttribute(typeof(ArgumentOutOfRangeException))]
		public void ParsePropertyTypeUnknownValue()
		{
			CommandFactory.ParsePropertyType("unknown");
		}
		
		/// <summary>
		/// Tests that parsing a property thows an exception when trying to parse null args.
		/// </summary>
		[Test, ExpectedExceptionAttribute(typeof(ArgumentNullException))]
		public void ParsePropertyTypeNullArgs()
		{
			CommandFactory.ParsePropertyType(null);
		}
		
		/// <summary>
		/// Test the Parse function correctly returns an instance of command given valid input data, 
		/// with no command arguments specified
		/// </summary>
		[Test]
		public void ParseWithNoCommandArgs()
		{
			Command command = CommandFactory.Parse(new string[] {"btnGo", "Click", null, "ById", "btnGo"});
			
			Assert.IsNotNull(command, "CommandFactory.Parse failed to return an instance of Command");
			Assert.AreEqual("btnGo", command.Id, "Command.Id not parsed correctly");
			Assert.AreEqual(CommandType.Click, command.CommandType, "Command.CommandType not parsed correctly");
			Assert.IsNotNull(command.Arguments, "Arguments not initialized correctly");
			Assert.AreEqual(0, command.Arguments.Count, "Arguments not initialized correctly");
			Assert.IsNotNull(command.FindMethod, "Command find method not initialized correctly");
			Assert.AreEqual(FindMethodTypes.ById, command.FindMethod.MethodType, "Command.FindMethod.MethodType not parsed correctly");
			Assert.AreEqual("btnGo", command.FindMethod.Arguments[0], "Command.FindMethod.Arguments not parsed correctly");
		}
	
		/// <summary>
		/// Test that you can parse a SetValue command type, that updates the text property of an text input field
		/// </summary>
		[Test]
		public void ParseSetValueCommandText()
		{
			Command command = CommandFactory.Parse(new string[] {"FirstName", "SetValue", "Edward,Text", "ById", "FirstName"});
			Assert.IsNotNull(command, "CommandFactory.Parse failed to return an instance of Command");
			Assert.AreEqual("FirstName", command.Id, "Command.Name not parsed correctly");
			Assert.AreEqual(CommandType.SetValue, command.CommandType, "Command.CommandType not parsed correctly");
			Assert.IsNotNull(command.Arguments, "Arguments not initialized correctly");
			Assert.AreEqual(2, command.Arguments.Count, "Arguments not initialized correctly");
			Assert.IsNotNull(command.FindMethod, "Command find method not initialized correctly");
			Assert.AreEqual(FindMethodTypes.ById, command.FindMethod.MethodType, "Command.FindMethod.MethodType not parsed correctly");
			Assert.AreEqual("FirstName", command.FindMethod.Arguments[0], "Command.FindMethod.Arguments not parsed correctly");
		}
		
		/// <summary>
		/// Test that when you can create a text command type and forget to pass in the text argument, i.e. the value you want
		/// to set the text field to, an error is thrown.
		/// </summary>
		[Test, ExpectedExceptionAttribute(typeof(ArgumentOutOfRangeException))]
		public void ParseCommandTextInvalidArgs()
		{
			Command command = CommandFactory.Parse(new string[] {"FirstName", "Text", null, "ById", "FirstName"});
			
		}
		
		/// <summary>
		/// Test the Parse function correctly returns an instance of command given valid input data, 
		/// with no find method specified
		/// </summary>
		[Test]
		public void ParseNoFindMethodSpecified()
		{
			Command command = CommandFactory.Parse(new string[] {"GotoTestPage", "Goto", "testpage1.htm", null, null});
			
			Assert.IsNotNull(command, "CommandFactory.Parse failed to return an instance of Command");
			Assert.AreEqual("GotoTestPage", command.Id, "Command.Name not parsed correctly");
			Assert.AreEqual(CommandType.GoTo, command.CommandType, "Command.CommandType not parsed correctly");
			Assert.IsNotNull(command.Arguments, "Command.Arguments not parsed correctly");
			Assert.AreEqual(1, command.Arguments.Count, "Command.Arguments not parsed correctly");
			Assert.IsNotNull(command.FindMethod, "Command find method not initialized correctly");
			Assert.AreEqual(FindMethodTypes.None, command.FindMethod.MethodType, "Command.FindMethod.MethodType not parsed correctly");
			Assert.AreEqual(0, command.FindMethod.Arguments.Count, "Command.FindMethod.Arguments not parsed correctly");
		}
		
		/// <summary>
		/// Test the parse function correctly handles invalid input data,
		/// in this case not passing in the correct number of parameters.
		/// </summary>
		[Test, ExpectedExceptionAttribute(typeof(ArgumentException))]
		public void ParseInvalidArgs()
		{
			Command command = CommandFactory.Parse(new string[] {"btnGo", "Click"});
		}
		
		/// <summary>
		/// Test the parse function correctly handles invalid input data,
		/// in this case not passing in the command type.
		/// </summary>
		[Test, ExpectedExceptionAttribute(typeof(ArgumentNullException))]
		public void ParseInvalidArgsNoCommandType()
		{
			Command command = CommandFactory.Parse(new string[] {"btnGo", null, null, "Find.ById", "link1"});
		}
		
		
		/// <summary>
		/// Test that we can correctly parse and return values of <see cref="CommandType" /> given appropriate input data.
		/// </summary>
		[Test]
		public void ParseCommandType()
		{
			Assert.AreEqual(CommandType.Click, CommandFactory.ParseCommandType("click"));
		}
		
		/// <summary>
		/// Test that parse method correctly handles invalid input data.
		/// </summary>
		[Test, ExpectedExceptionAttribute(typeof(ArgumentOutOfRangeException))]
		public void ParseCommandTypeInvalidArgs()
		{
			Assert.AreEqual(CommandType.Click, CommandFactory.ParseCommandType("clickzz"));
		}

        /// <summary>
        /// Parses the command args with quotes.
        /// Sometimes you will want to pass in arguments with quotes i.e. SetCookie, http://test.com, "cookie-name=bob; expires=Wed, 01-Jan-2020 00:00:00 GMT"
        /// </summary>
        [Test]
        public void ParseCommandArgsWithQuotes()
        {
            string arguments = "http://test.com,\"cookie-name=bob; expires=Wed, 01-Jan-2020 00:00:00 GMT\"";
            string[] parsedArguments = CommandFactory.ParseArguments(arguments);

            Assert.AreEqual(2, parsedArguments.Length, "Incorrect number of arguments parsed");
            Assert.AreEqual("http://test.com", parsedArguments[0]);
            Assert.AreEqual("cookie-name=bob; expires=Wed, 01-Jan-2020 00:00:00 GMT", parsedArguments[1]);
        }
	}
}
